<template>
  <div class="m-[25px_15px] md:m-[25px_40px] xl:m-[50px]">
    <div class="flex items-center mb-[15px]">
      <div class="mr-[30px]">
        <label class="mr-[10px] text-xs xl:text-sm" for="credits_category">
          Department
        </label>
        <select
          class="p-[8px_35px_8px_15px] text-[13px] text-white bg-secondary bg-[url('@/assets/images/select-arrow.svg')] bg-no-repeat bg-[100%_45%] bg-[length:30px_60px] border-secondary appearance-none rounded-[0] disabled:cursor-default disabled:opacity-40"
          id="credits_category"
          v-model="activeCategory"
          :disabled="!categories.length || categories.length === 1"
          @change="filterCredits"
        >
          <option value="all">All</option>
          <option
            v-for="category in categories"
            :key="`credit-filter-${category.toLowerCase()}`"
            :value="category.toLowerCase()"
          >
            {{ category }}
          </option>
        </select>
      </div>

      <div class="mr-[30px]">
        <label class="mr-[10px] text-xs xl:text-sm"> Media </label>

        <select
          class="p-[8px_35px_8px_15px] text-[13px] text-white bg-secondary bg-[url('@/assets/images/select-arrow.svg')] bg-no-repeat bg-[100%_45%] bg-[length:30px_60px] border-secondary appearance-none rounded-[0] disabled:cursor-default disabled:opacity-40"
          id="credits_media"
          v-model="activeMedia"
          @change="onGetCredits"
        >
          <option value="combined_credits">All</option>
          <option value="movie_credits">Movies</option>
          <option value="tv_credits">TV Shows</option>
        </select>
      </div>
    </div>

    <div
      v-for="category in activeCredits"
      :key="`credits-${category.name.toLowerCase()}`"
      class="mb-[30px]"
    >
      <h2 class="mb-[15px] text-lg xl:mb-4 text-[24px]">
        {{ category.name }}
      </h2>

      <table class="w-full border-collapse">
        <tbody>
          <CreditsHistoryGroup
            v-for="group in category.groups"
            :key="`credit-${category.name.toLowerCase()}-${group.year}`"
            :group="group"
          />
        </tbody>
      </table>
    </div>
  </div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import { getCredits } from "@/api";
import CreditsHistoryGroup from "./CreditsHistoryGroup.vue";

let active_media = [];

const { credits } = defineProps({
  credits: {
    type: Object,
    required: true,
  },
});

const route = useRoute();
const activeMedia = ref("combined_credits");
const activeCategory = ref("all");
const categories = ref([]);
const activeCredits = ref(null);

const handleCast = (items) => {
  if (!items || !items.length) return;

  let groups = groupItems(items);

  const blankGroup = groups.find((group) => group.year === "");

  if (blankGroup) groups = groups.filter((group) => group.year !== "");

  sortGroups(groups);

  if (blankGroup) groups.unshift(blankGroup);

  groups.forEach((group) => sortCredits(group.credits));

  return groups;
};

onMounted(() => {
  const cast = handleCast(credits.cast);
  const crew = handleCrew(credits.crew);

  if (cast) active_media.push({ name: "Acting", groups: cast });
  if (crew) active_media = [...active_media, ...crew];

  activeCredits.value = active_media;


  categories.value = getCategories();
});

const handleCrew = (items) => {
  if (!items || !items.length) return;

  const categories = createCategories(items);

  categories.forEach((category) => {
    let groups = groupItems(category.groups);

    const blankGroup = groups.find((group) => group.year === "");

    if (blankGroup) groups = groups.filter((group) => group.year !== "");

    sortGroups(groups);

    if (blankGroup) groups.unshift(blankGroup);

    groups.forEach((group) => sortCredits(group.credits));

    category.groups = groups;
  });

  return categories;
};

const getCategories = () => {
  return activeCredits.value.map((category) => category.name);
};

const onGetCredits = () => {
  if (active_media && active_media.length) {
    activeCredits.value = active_media;
    activeCategory.value = "all";
    categories.value = getCategories();
  } else {
    getCredits(route.params.id, activeMedia.value).then((response) => {
      const cast = handleCast(response.cast);
      const crew = handleCrew(response.crew);

      if (cast) active_media.push({ name: "Acting", groups: cast });
      if (crew) active_media = [...active_media, ...crew];

      activeCredits.value = active_media;
      activeCategory.value = "all";
      categories.value = getCategories();
    });
  }
};
const sortGroups = (items) => {
  return items.sort((a, b) => (a.year > b.year ? -1 : 1));
};

const sortCredits = (items) => {
  return items.sort((a, b) => {
    const aDate = a.release_date ?? a.first_air_date;
    const bDate = b.release_date ?? b.first_air_date;
    if (aDate > bDate) {
      return -1;
    } else if (aDate < bDate) {
      return 1;
    }
    return 0;
  });
};

const filterCredits = () => {
  if (activeCategory.value === "all") {
    activeCredits.value = active_media;
  } else {
    activeCredits.value = active_media.filter(
      (category) => category.name.toLowerCase() === activeCategory.value
    );
  }
};

const createCategories = (items) => {
  const categories = [];

  items.forEach((item) => {
    const exists = categories.find(
      (category) => category.name === item.department
    );

    if (exists) {
      exists.groups.push(item);
    } else {
      categories.push({
        name: item.department,
        groups: [item],
      });
    }
  });

  return categories;
};

const groupItems = (items) => {
  return items.reduce(function (arr, current) {
    const date = current.release_date
      ? current.release_date
      : current.first_air_date;
    const year = date ? date.split("-")[0] : "";
    const exists = arr.find((item) => item.year === year);

    if (exists) {
      exists.credits.push(current);
    } else {
      arr.push({
        year,
        credits: [current],
      });
    }
    return arr;
  }, []);
};
</script>
